<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\ChannelCode\Logic;

use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Common\Constants\BusinessLog\Event;
use MoChat\App\Common\Contract\BusinessLogContract;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Plugin\ChannelCode\Constants\Status;
use MoChat\Plugin\ChannelCode\Contract\ChannelCodeContract;
use MoChat\Plugin\ChannelCode\Logic\Traits\ChannelCodeTrait;

/**
 * 新建渠道码.
 *
 * Class StoreLogic
 */
class StoreLogic
{
    use ChannelCodeTrait;

    /**
     * 渠道码表.
     * @Inject
     * @var ChannelCodeContract
     */
    private $channelCode;

    /**
     * @Inject
     * @var BusinessLogContract
     */
    private $businessLog;

    /**
     * @Inject
     * @var StdoutLoggerInterface
     */
    private $logger;

    /**
     * 参数.
     * @var array
     */
    private $params;

    /**
     * @return array
     */
    public function handle(array $params)
    {
        $this->params = $params;

        // 校验引流成员每个时间段配置的企业成员人数 （微信[联系我]中每个联系方式最多配置100个使用成员（包含部门展开后的成员））
        $this->checkEmployee();

        // 开启事务
        Db::beginTransaction();
        try {
            // 插入渠道码表
            $res = $this->addChannelCode();
            // 记录日志
            $this->recordLog($res);
            // 更新二维码
            $this->handleQrCode(
                $this->params['drainageEmployee'],
                (int) $this->params['baseInfo']['autoAddFriend'],
                (int) user()['corpIds'][0],
                (int) $res
            );
            Db::commit();
        } catch (\Throwable $ex) {
            Db::rollBack();
            $this->logger->error(sprintf('新建渠道码失败: %s', Json::encode($params)));
            throw new CommonException(ErrorCode::INVALID_PARAMS, $ex->getMessage());
        }

        return [];
    }

    /**
     * 添加渠道码
     * @return int
     */
    private function addChannelCode()
    {
        // 添加参数
        $data = [
            'corp_id' => user()['corpIds'][0],
            'group_id' => $this->params['baseInfo']['groupId'],
            'name' => $this->params['baseInfo']['name'],
            'auto_add_friend' => $this->params['baseInfo']['autoAddFriend'],
            'tags' => Json::encode($this->params['baseInfo']['tags']),
            'type' => $this->params['type'],
            'drainage_employee' => Json::encode($this->params['drainageEmployee']),
            'welcome_message' => Json::encode($this->params['welcomeMessage']),
            'span_welcome_status' => $this->params['spanWelcomeStatus'],
            'span_welcome' => isset($this->params['spanWelcome']) ? Json::encode($this->params['spanWelcome']) : '{}',
            'contact_remark' => isset($this->params['baseInfo']['contactRemark']) ? Json::encode($this->params['baseInfo']['contactRemark']) : '{}',
            'contact_description' => $this->params['baseInfo']['contactDescription'] ?? '',
            'close_words' => Json::encode($this->params['closeWords']),
            'created_at' => date('Y-m-d H:i:s'),
            'image' => $this->params['baseInfo']['image'] ?? '',
            'creator_id' => $this->params['employeeId'],
        ];
        // 插入渠道码表
        $res = $this->channelCode->createChannelCode($data);
        if (! is_int($res)) {
            throw new CommonException(ErrorCode::SERVER_ERROR, '新建渠道码失败');
        }

        return $res;
    }

    /**
     * 记录日志.
     * @param $channelCodeId
     */
    private function recordLog($channelCodeId)
    {
        $params = [
            'baseInfo' => $this->params['baseInfo'],
            'drainageEmployee' => $this->params['drainageEmployee'],
            'welcomeMessage' => $this->params['welcomeMessage'],
        ];
        // 记录日志表
        $data = [
            'business_id' => $channelCodeId,
            'params' => Json::encode($params),
            'event' => Event::CHANNEL_CODE_CREATE,
            'operation_id' => user()['workEmployeeId'],
            'updated_at' => date('Y-m-d H:i:s'),
        ];

        $logRes = $this->businessLog->createBusinessLog($data);
        if (! is_int($logRes)) {
            throw new CommonException(ErrorCode::SERVER_ERROR, '新建渠道码日志记录失败');
        }
    }

    /**
     * 校验每个时间段配置的企业成员人数.
     * @return array|bool
     */
    private function checkEmployee()
    {
        // 类型不需要校验
        if ($this->params['drainageEmployee']['addMax']['status'] === Status::CLOSE) {
            return [];
        }

        // 处理客户添加上限
        if ($this->params['drainageEmployee']['addMax']['status'] === Status::OPEN) {
            foreach ($this->params['drainageEmployee']['addMax']['employees'] as $item) {
                if ($item['max'] > 20000) {
                    throw new CommonException(ErrorCode::SERVER_ERROR, '每日添加客户上限为20000');
                }
            }
        }
        return true;
    }
}
